﻿using System;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;

namespace SBPweb.PhotoGallery.Common
{

    public class DownloadManager
    {

        #region Private fields

        private WebClientPool clientPool = new WebClientPool();
        //private Dictionary<Guid, DownloadItem> downloads = new Dictionary<Guid, DownloadItem>();

        #endregion

        #region Constructor logic

        public DownloadManager()
        {
        }

        #endregion

        #region Property accessors

        #endregion

        #region Events

        public event EventHandler<DownloadEventArgs> DownloadStarted;

        public event EventHandler<DownloadErrorEventArgs> DownloadError;

        public event EventHandler<DownloadEventArgs> DownloadCancelled;

        public event EventHandler<DownloadProgressEventArgs> DownloadProgressChanged;

        public event EventHandler<DownloadStreamEventArgs> DownloadCompleted;

        #endregion

        #region Methods
        
        public void DownloadAsync(DownloadItem item)
        {
            WebClient client = clientPool.GetClientInstance();
            clientPool.SetClientBusy(client);
            client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
            client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);

            item.FireOnDownloadStarted();
            OnDownloadStarted(this, new DownloadEventArgs(item));
            client.OpenReadAsync(item, item);
        }

        #region Event handlers

        private void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            DownloadItem item = e.UserState as DownloadItem;
            try
            {
                if (e.Cancelled)
                {
                    item.FireOnDownloadCancelled();
                    OnDownloadCancelled(this, new DownloadEventArgs(item));
                }
                if (e.Error != null)
                {
                    throw e.Error;
                }
                item.FireOnDownloadCompleted(e.Result);
                OnDownloadCompleted(this, new DownloadStreamEventArgs(item, e.Result));
            }
            catch (Exception ex)
            {
                item.FireOnDownloadError(ex);
                OnDownloadError(this, new DownloadErrorEventArgs(item, ex));
            }
        }

        private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            DownloadItem item = e.UserState as DownloadItem;
            item.FireOnDownloadProgressChanged(e);
            OnDownloadProgressChanged(this, new DownloadProgressEventArgs(item, e));
        }

        protected virtual void OnDownloadStarted(object sender, DownloadEventArgs e)
        {
            if (DownloadStarted != null)
            {
                DownloadStarted(sender, e);
            }
        }

        protected virtual void OnDownloadError(object sender, DownloadErrorEventArgs e)
        {
            if (DownloadError != null)
            {
                DownloadError(sender, e);
            }
        }

        protected virtual void OnDownloadCancelled(object sender, DownloadEventArgs e)
        {
            if (DownloadCancelled != null)
            {
                DownloadCancelled(sender, e);
            }
        }

        protected virtual void OnDownloadProgressChanged(object sender, DownloadProgressEventArgs e)
        {
            if (DownloadProgressChanged != null)
            {
                DownloadProgressChanged(sender, e);
            }
        }

        protected virtual void OnDownloadCompleted(object sender, DownloadStreamEventArgs e)
        {
            if (DownloadCompleted != null)
            {
                DownloadCompleted(sender, e);
            }
        }

        #endregion

        #endregion

    }

}